"""
FMCW雷达系统主类
整合信号发生器、频谱分析仪、数据处理和数据保存模块
"""

import numpy as np
import time
from typing import Dict, Any, Optional, Tuple
from pathlib import Path

from src.config_manager import ConfigManager
from src.logger import Logger
from src.signal_generator import SignalGenerator
from src.spectrum_analyzer import SpectrumAnalyzer
# 移除DataProcessor模块，因为不再需要STFT分析
# from src.data_processor import DataProcessor
from src.data_saver import DataSaver
from src.time_sync import TimeSync, TimeEvent
from src.fast_slow_time_processor import FastSlowTimeProcessor


class FMCWRadarSystem:
    """FMCW雷达系统主控制器"""
    
    def __init__(self, config_path: str = "config/config.json"):
        """
        初始化FMCW雷达系统
        
        Args:
            config_path: 配置文件路径
        """
        # 加载配置
        self.config_manager = ConfigManager(config_path)
        self.config = self.config_manager.load_config()
        
        # 初始化日志记录器
        logging_config = self.config_manager.get_logging_config()
        self.logger = Logger("fmcw_radar", logging_config)
        
        # 初始化各个模块
        self.signal_generator = None
        self.spectrum_analyzer = None
        self.data_saver = None
        self.fast_slow_processor = None
        
        # 系统状态
        self.is_initialized = False
        self.iq_data = None
        self.chirp_matrix = None
        self.chirp_processing_info = None
        
        # 初始化时间同步器
        self.time_sync = TimeSync(self.logger)
        
        self.logger.info("=" * 60)
        self.logger.info("FMCW雷达系统初始化")
        self.logger.info("=" * 60)
        
    def initialize_system(self) -> bool:
        """
        初始化系统各个模块
        
        Returns:
            初始化是否成功
        """
        try:
            self.logger.info("正在初始化系统模块...")
            
            # 初始化信号发生器
            smw_config = self.config_manager.get_instrument_config('smw')
            self.signal_generator = SignalGenerator(smw_config, self.logger)
            
            # 初始化频谱分析仪
            fsw_config = self.config_manager.get_instrument_config('fsw')
            self.spectrum_analyzer = SpectrumAnalyzer(fsw_config, self.logger)
            
            # 移除数据处理器，不再需要STFT分析
            
            # 初始化数据保存器
            output_config = self.config_manager.get_output_config()
            self.data_saver = DataSaver(output_config, self.logger)
            
            # 初始化快慢时间处理器
            fast_slow_config = self.config_manager.get_fast_slow_time_config()
            if fast_slow_config.get('enable_processing', False):
                # 合并fmcw_signal配置用于时序计算
                full_fast_slow_config = fast_slow_config.copy()
                full_fast_slow_config['fmcw_signal'] = self.config_manager.get_fmcw_config()
                
                self.fast_slow_processor = FastSlowTimeProcessor(full_fast_slow_config, self.logger)
                self.logger.info("✓ 快慢时间处理器已初始化")
            else:
                self.logger.info("快慢时间处理功能已禁用")
            
            self.is_initialized = True
            self.logger.info("✓ 系统模块初始化完成")
            return True
            
        except Exception as e:
            self.logger.error(f"系统初始化失败: {e}")
            return False
    
    def connect_instruments(self) -> bool:
        """
        连接仪器
        
        Returns:
            连接是否成功
        """
        if not self.is_initialized:
            self.logger.error("系统未初始化，请先调用initialize_system()")
            return False
        
        try:
            self.logger.info("正在连接仪器...")
            
            # 连接SMW信号发生器
            if not self.signal_generator.connect():
                self.logger.error("连接SMW信号发生器失败")
                return False
            
            # 连接FSW频谱分析仪
            if not self.spectrum_analyzer.connect():
                self.logger.error("连接FSW频谱分析仪失败")
                return False
            
            self.logger.info("✓ 仪器连接成功")
            return True
            
        except Exception as e:
            self.logger.error(f"连接仪器失败: {e}")
            return False
    
    def generate_fmcw_signal(self, auto_scale: bool = False) -> bool:
        """
        生成FMCW信号
        
        Args:
            auto_scale: 是否使用自动缩放
            
        Returns:
            生成是否成功
        """
        try:
            self.logger.info("正在生成FMCW信号...")
            
            # 获取FMCW配置
            fmcw_config = self.config_manager.get_fmcw_config()
            
            # 生成信号
            success = self.signal_generator.generate_fmcw_signal(fmcw_config, auto_scale)
            
            if success:
                self.logger.info("✓ FMCW信号生成完成")
            else:
                self.logger.error("✗ FMCW信号生成失败")
            
            return success
            
        except Exception as e:
            self.logger.error(f"生成FMCW信号失败: {e}")
            return False
    
    def acquire_iq_data(self) -> bool:
        """
        采集IQ数据
        
        Returns:
            采集是否成功
        """
        try:
            self.logger.info("正在采集IQ数据...")
            
            # 获取采集配置
            smw_config = self.config_manager.get_instrument_config('smw')
            fsw_config = self.config_manager.get_instrument_config('fsw')
            trigger_config = self.config_manager.get_trigger_config()
            
            center_freq = fsw_config.get('center_frequency', 10) #捕捉拍频信号，就是这么设置的
            ref_level = fsw_config.get('reference_level', -20)
            sample_rate = fsw_config.get('sample_rate', 100e3)
            capture_time = fsw_config.get('capture_time', 1.0)
            
            # 采集IQ数据
            success = self.spectrum_analyzer.acquire_iq_with_config(
                center_freq=center_freq,
                ref_level=ref_level,
                sample_rate=sample_rate,
                capture_time=capture_time,
                trigger_config=trigger_config
            )
            
            if success:
                self.iq_data = self.spectrum_analyzer.get_iq_data()
                self.logger.info(f"✓ IQ数据采集完成，数据长度: {len(self.iq_data)}")
            else:
                self.logger.error("✗ IQ数据采集失败")
            
            return success
            
        except Exception as e:
            self.logger.error(f"采集IQ数据失败: {e}")
            return False
    
    # 移除process_and_analyze方法，不再需要STFT分析
    
    def save_session_data(self) -> bool:
        """
        保存IQ数据（简化版本，不包含STFT分析）
        
        Returns:
            保存是否成功
        """
        try:
            if self.iq_data is None:
                self.logger.error("没有IQ数据可保存")
                return False
            
            self.logger.info("正在保存IQ数据...")
            
            # 获取参数
            smw_config = self.config_manager.get_instrument_config('smw')
            fsw_config = self.config_manager.get_instrument_config('fsw')
            sample_rate = fsw_config.get('sample_rate', 100e3)
            center_freq = smw_config.get('center_frequency', 10e9)
            
            # 保存IQ数据
            return self._save_iq_data_only()
            
        except Exception as e:
            self.logger.error(f"保存IQ数据失败: {e}")
            return False
    
    def run_complete_sequence_with_timing(self, auto_scale: bool = False, save_data: bool = True) -> bool:
        """
        运行完整的FMCW雷达测试序列（包含时间同步）
        当前实现顺序：先准备频谱仪并启动采集等待触发，再启用信号源输出
        
        Args:
            auto_scale: 是否使用自动缩放
            save_data: 是否保存数据
            
        Returns:
            序列执行是否成功
        """
        try:
            self.logger.info("=" * 60)
            self.logger.info("开始FMCW雷达测试序列（时序控制版本）")
            self.logger.info("=" * 60)
            
            # 记录开始时间
            self.time_sync.record_event(TimeEvent.SEQUENCE_START, "序列开始")
            
            # 获取时序控制配置
            timing_config = self.config.get('timing_control', {})
            preparation_delay = timing_config.get('preparation_delay', 0.1)
            spectrum_to_signal_delay = timing_config.get('spectrum_to_signal_delay', 3.0)
            output_delay = timing_config.get('output_delay', 0.05)
            trigger_delay = timing_config.get('trigger_delay', 0.01)
            
            self.logger.info(f"时序控制参数: 准备延迟={preparation_delay}s, 频谱仪到信号源延迟={spectrum_to_signal_delay}s, 输出延迟={output_delay}s, 触发延迟={trigger_delay}s")
            
            # 初始化系统
            self.time_sync.record_event(TimeEvent.SYSTEM_INIT, "系统初始化开始")
            if not self.initialize_system():
                return False
            self.time_sync.record_event(TimeEvent.SYSTEM_INIT_COMPLETE, "系统初始化完成")
            
            # 连接仪器
            self.time_sync.record_event(TimeEvent.INSTRUMENT_CONNECT, "仪器连接开始")
            if not self.connect_instruments():
                return False
            self.time_sync.record_event(TimeEvent.INSTRUMENT_CONNECT_COMPLETE, "仪器连接完成")
            
            # 准备频谱仪（进入触发就绪状态）
            self.time_sync.record_event(TimeEvent.SPECTRUM_PREPARE, "频谱仪准备开始")
            if not self._prepare_spectrum_analyzer():
                return False
            self.time_sync.record_event(TimeEvent.SPECTRUM_PREPARE_COMPLETE, "频谱仪准备完成")
            
            # 等待频谱仪到信号源的延迟（3秒）
            if spectrum_to_signal_delay > 0:
                self.logger.info(f"等待频谱仪到信号源延迟: {spectrum_to_signal_delay}s")
                time.sleep(spectrum_to_signal_delay)
            
            # 准备信号源（不立即输出）
            self.time_sync.record_event(TimeEvent.SIGNAL_PREPARE, "信号源准备开始")
            if not self._prepare_signal_generator(auto_scale):
                return False
            self.time_sync.record_event(TimeEvent.SIGNAL_PREPARE_COMPLETE, "信号源准备完成")
            
            # 等待准备延迟
            if preparation_delay > 0:
                self.logger.info(f"等待准备延迟: {preparation_delay}s")
                time.sleep(preparation_delay)
            
            # 启动频谱仪触发采集
            self.time_sync.record_event(TimeEvent.SPECTRUM_TRIGGER, "频谱仪触发采集开始")
            if not self._start_spectrum_acquisition():
                return False
            self.time_sync.record_event(TimeEvent.SPECTRUM_TRIGGER_COMPLETE, "频谱仪触发采集完成")
            
            # 等待触发延迟后开启信号源输出
            if trigger_delay > 0:
                self.logger.info(f"等待触发延迟: {trigger_delay}s")
                time.sleep(trigger_delay)
            
            # 启用信号源输出
            self.time_sync.record_event(TimeEvent.SIGNAL_OUTPUT, "信号源输出开始")
            if not self._enable_signal_output(output_delay):
                return False
            self.time_sync.record_event(TimeEvent.SIGNAL_OUTPUT_COMPLETE, "信号源输出完成")
            
            # 读取IQ数据
            self.time_sync.record_event(TimeEvent.DATA_ACQUISITION, "数据读取开始")
            if not self._read_iq_data():
                return False
            self.time_sync.record_event(TimeEvent.DATA_ACQUISITION_COMPLETE, "数据读取完成")
            
            # 保存IQ数据，不进行STFT分析
            if save_data:
                self.logger.info("保存IQ数据（跳过STFT分析）")
                self.time_sync.record_event(TimeEvent.DATA_SAVE, "数据保存开始")
                if not self._save_iq_data_only():
                    return False
                self.time_sync.record_event(TimeEvent.DATA_SAVE_COMPLETE, "数据保存完成")
            
            # 记录序列完成
            self.time_sync.record_event(TimeEvent.SEQUENCE_COMPLETE, "序列完成")
            
            # 打印时序总结
            self._log_timing_summary()
            
            self.logger.info("=" * 60)
            self.logger.info("FMCW雷达测试序列完成（时序控制版本）")
            self.logger.info("=" * 60)
            
            return True
            
        except Exception as e:
            self.logger.error(f"FMCW雷达测试序列失败: {e}")
            return False

    def run_sequence_source_first(self, auto_scale: bool = False, save_data: bool = True,
                                  warmup_seconds: float = 3.0) -> bool:
        """
        按用户要求的顺序运行：
        1) 最先配置好信号源并立即输出；
        2) 等待 warmup_seconds（默认 3s）；
        3) 立刻配置频谱仪并启动触发等待，采集数据；
        4) 可选保存数据。

        Args:
            auto_scale: SMW 是否使用自动缩放波形
            save_data: 是否保存数据
            warmup_seconds: 启动信号源后的等待时间（秒）

        Returns:
            是否成功
        """
        try:
            self.logger.info("=" * 60)
            self.logger.info("开始按‘先信号源后频谱仪’顺序运行")
            self.logger.info("=" * 60)

            # 初始化与连接
            if not self.initialize_system():
                return False
            if not self.connect_instruments():
                return False

            # 1) 立即配置并开启信号源输出
            fmcw_config = self.config_manager.get_fmcw_config()
            if not self.signal_generator.generate_fmcw_signal(
                fmcw_config, auto_scale=auto_scale, enable_immediately=True
            ):
                return False

            # 2) 等待 warmup
            if warmup_seconds and warmup_seconds > 0:
                self.logger.info(f"信号源已输出，等待 {warmup_seconds:.2f}s...")
                time.sleep(warmup_seconds)

            # 3) 配置频谱仪并触发采集
            if not self._prepare_spectrum_analyzer():
                return False
            if not self._start_spectrum_acquisition():
                return False

            # 4) 保存数据（按现有保存逻辑，仅IQ+可选快慢时间矩阵）
            if save_data:
                if not self._save_iq_data_only():
                    return False

            self.logger.info("=" * 60)
            self.logger.info("按‘先信号源后频谱仪’顺序运行完成")
            self.logger.info("=" * 60)
            return True

        except Exception as e:
            self.logger.error(f"按‘先信号源后频谱仪’顺序运行失败: {e}")
            return False

    def run_complete_sequence(self, auto_scale: bool = False, save_data: bool = True) -> bool:
        """
        运行简化的FMCW雷达测试序列（无STFT分析）
        
        Args:
            auto_scale: 是否使用自动缩放
            save_data: 是否保存数据
            
        Returns:
            序列执行是否成功
        """
        try:
            self.logger.info("=" * 60)
            self.logger.info("开始FMCW雷达测试序列（简化版本）")
            self.logger.info("=" * 60)
            
            # 初始化系统
            if not self.initialize_system():
                return False
            
            # 连接仪器
            if not self.connect_instruments():
                return False
            
            # 生成FMCW信号
            if not self.generate_fmcw_signal(auto_scale):
                return False
            
            # 采集IQ数据
            if not self.acquire_iq_data():
                return False
            
            # 保存数据
            if save_data:
                if not self.save_session_data():
                    return False
            
            self.logger.info("=" * 60)
            self.logger.info("FMCW雷达测试序列完成")
            self.logger.info("=" * 60)
            
            return True
            
        except Exception as e:
            self.logger.error(f"FMCW雷达测试序列失败: {e}")
            return False
    
    def get_system_status(self) -> Dict[str, Any]:
        """
        获取系统状态
        
        Returns:
            系统状态字典
        """
        status = {
            'initialized': self.is_initialized,
            'has_iq_data': self.iq_data is not None,
            'has_chirp_matrix': self.chirp_matrix is not None,
            'instruments': {}
        }
        
        if self.signal_generator:
            status['instruments']['smw'] = self.signal_generator.get_instrument_info()
        
        if self.spectrum_analyzer:
            status['instruments']['fsw'] = self.spectrum_analyzer.get_instrument_info()
        
        return status
    
    def cleanup(self) -> None:
        """清理系统资源"""
        try:
            if hasattr(self, 'logger') and self.logger:
                self.logger.info("正在清理系统资源...")
            
            if hasattr(self, 'signal_generator') and self.signal_generator:
                self.signal_generator.disconnect()
            
            if hasattr(self, 'spectrum_analyzer') and self.spectrum_analyzer:
                self.spectrum_analyzer.disconnect()
            
            if hasattr(self, 'is_initialized'):
                self.is_initialized = False
                
            if hasattr(self, 'logger') and self.logger:
                self.logger.info("✓ 系统资源清理完成")
            
        except Exception as e:
            if hasattr(self, 'logger') and self.logger:
                self.logger.error(f"清理系统资源失败: {e}")
    
    def _prepare_spectrum_analyzer(self) -> bool:
        """
        准备频谱分析仪（进入触发就绪状态）
        
        Returns:
            准备是否成功
        """
        try:
            # 获取配置
            smw_config = self.config_manager.get_instrument_config('smw')
            fsw_config = self.config_manager.get_instrument_config('fsw')
            trigger_config = self.config_manager.get_trigger_config()
            
            center_freq = fsw_config.get('center_frequency', 10e9)
            ref_level = fsw_config.get('reference_level', -20)
            sample_rate = fsw_config.get('sample_rate', 100e3)
            capture_time = fsw_config.get('capture_time', 1.0)
            
            # 配置基本设置
            if not self.spectrum_analyzer.configure_basic_settings(center_freq, ref_level):
                return False
            
            # 配置IQ分析仪
            if not self.spectrum_analyzer.configure_iq_analyzer(sample_rate, capture_time):
                return False
            
            # 配置触发器但不启动采集
            if not self.spectrum_analyzer.configure_trigger(trigger_config, capture_time):
                return False
            
            # 准备触发状态
            if not self.spectrum_analyzer.prepare_for_trigger(trigger_config):
                return False
            
            self.logger.info("频谱分析仪已准备就绪，等待触发")
            return True
            
        except Exception as e:
            self.logger.error(f"准备频谱分析仪失败: {e}")
            return False
    
    def _prepare_signal_generator(self, auto_scale: bool = False) -> bool:
        """
        准备信号发生器（不立即启用输出）
        
        Args:
            auto_scale: 是否使用自动缩放
            
        Returns:
            准备是否成功
        """
        try:
            # 获取FMCW配置
            fmcw_config = self.config_manager.get_fmcw_config()
            
            # 准备信号但不启用输出
            if not self.signal_generator.prepare_fmcw_signal(fmcw_config, auto_scale):
                return False
            
            self.logger.info("信号发生器已准备就绪，输出暂未启用")
            return True
            
        except Exception as e:
            self.logger.error(f"准备信号发生器失败: {e}")
            return False
    
    def _start_spectrum_acquisition(self) -> bool:
        """
        启动频谱仪触发采集
        
        Returns:
            启动是否成功
        """
        try:
            if not self.spectrum_analyzer.start_triggered_acquisition():
                return False
            
            # 读取IQ数据
            if not self.spectrum_analyzer.acquire_iq_data():
                return False
            
            self.iq_data = self.spectrum_analyzer.get_iq_data()
            self.logger.info(f"IQ数据采集完成，数据长度: {len(self.iq_data)}")
            return True
            
        except Exception as e:
            self.logger.error(f"启动频谱仪采集失败: {e}")
            return False
    
    def _enable_signal_output(self, delay_seconds: float = 0.0) -> bool:
        """
        启用信号源输出
        
        Args:
            delay_seconds: 延迟时间
            
        Returns:
            启用是否成功
        """
        try:
            if not self.signal_generator.enable_output_with_delay(delay_seconds):
                return False
            
            self.logger.info("信号源输出已启用")
            return True
            
        except Exception as e:
            self.logger.error(f"启用信号源输出失败: {e}")
            return False
    
    def _read_iq_data(self) -> bool:
        """
        读取IQ数据（从频谱仪缓存）
        
        Returns:
            读取是否成功
        """
        try:
            if self.iq_data is None:
                # 如果没有数据，尝试从频谱仪读取
                if not self.spectrum_analyzer.acquire_iq_data():
                    return False
                self.iq_data = self.spectrum_analyzer.get_iq_data()
            
            if self.iq_data is None:
                self.logger.error("无法获取IQ数据")
                return False
            
            self.logger.info("IQ数据读取完成")
            return True
            
        except Exception as e:
            self.logger.error(f"读取IQ数据失败: {e}")
            return False
    
    # 移除_save_session_with_timing方法，不再需要
    
    def _log_timing_summary(self) -> None:
        """
        打印时序总结
        """
        try:
            all_events = self.time_sync.get_all_events()
            
            self.logger.info("=" * 60)
            self.logger.info("时序控制总结")
            self.logger.info("=" * 60)
            
            # 计算相对时间
            reference_time = self.time_sync.get_event_time(TimeEvent.SYSTEM_START)
            
            for event, timestamp in all_events.items():
                relative_time = timestamp - reference_time if reference_time is not None else 0
                self.logger.info(f"{event.value}: {timestamp:.3f}s ({relative_time:.3f}s)")
            
            # 计算总耗时
            if TimeEvent.SEQUENCE_COMPLETE in all_events and TimeEvent.SEQUENCE_START in all_events:
                total_time = self.time_sync.get_relative_time(
                    TimeEvent.SEQUENCE_COMPLETE, TimeEvent.SEQUENCE_START
                )
                if total_time is not None:
                    self.logger.info(f"总耗时: {total_time:.3f}s")
            
            self.logger.info("=" * 60)
            
        except Exception as e:
            self.logger.error(f"打印时序总结失败: {e}")

    def _save_iq_data_only(self) -> bool:
        """
        保存IQ数据并处理快慢时间矩阵（如果启用）
        
        Returns:
            保存是否成功
        """
        try:
            if self.iq_data is None:
                self.logger.error("没有IQ数据可保存")
                return False
            
            self.logger.info("正在保存IQ数据并处理快慢时间矩阵...")
            
            # 获取参数
            smw_config = self.config_manager.get_instrument_config('smw')
            fsw_config = self.config_manager.get_instrument_config('fsw')
            sample_rate = fsw_config.get('sample_rate', 100e3)
            center_freq = smw_config.get('center_frequency', 10e9)
            
            # 获取时序元数据
            timing_metadata = self.time_sync.create_timing_metadata()
            
            # 计算时间偏移数组
            time_offsets = np.arange(len(self.iq_data)) / sample_rate
            
            # 创建基础元数据
            base_metadata = {
                'session_type': 'fast_slow_time_acquisition',
                'skipped_stft_analysis': True,
                'acquisition_config': {
                    'sample_rate': sample_rate,
                    'center_frequency': center_freq,
                    'data_length': len(self.iq_data)
                }
            }
            
            # 保存IQ数据（包含时序信息）
            saved_files = self.data_saver.save_iq_data(
                iq_data=self.iq_data,
                sample_rate=sample_rate,
                center_freq=center_freq,
                metadata=base_metadata,
                time_offsets=time_offsets,
                timing_metadata=timing_metadata
            )
            
            # 快慢时间矩阵处理（如果启用）
            fast_slow_config = self.config_manager.get_fast_slow_time_config()
            if fast_slow_config.get('enable_processing', False):
                self.logger.info("开始快慢时间矩阵处理...")
                
                try:
                    # 创建IQ数据的复数数组
                    iq_data_complex = self.iq_data[0::2] + 1j * self.iq_data[1::2]
                    
                    # 处理IQ数据生成chirp矩阵
                    self.chirp_matrix, processing_info = self.fast_slow_processor.process_iq_to_matrix(
                        iq_data_complex, sample_rate
                    )
                    self.chirp_processing_info = processing_info
                    
                    # 保存chirp矩阵
                    chirp_files = self.data_saver.save_chirp_matrix(
                        chirp_matrix=self.chirp_matrix,
                        processing_info=processing_info,
                        sample_rate=sample_rate,
                        center_freq=center_freq
                    )
                    
                    if chirp_files:
                        saved_files.update(chirp_files)
                        self.logger.info(f"✓ 快慢时间矩阵处理完成，生成了 {self.chirp_matrix.shape[0]} 个chirp")
                        self.logger.info(f"矩阵形状: {self.chirp_matrix.shape}")
                        self.logger.info(f"快时间窗口: {processing_info['fast_time_window']*1e6:.1f} μs")
                        self.logger.info(f"慢时间维度: {processing_info['slow_time_points']} 个chirp")
                    else:
                        self.logger.warning("快慢时间矩阵保存失败")
                    
                except Exception as e:
                    self.logger.error(f"快慢时间矩阵处理失败: {e}")
                    self.chirp_matrix = None
                    self.chirp_processing_info = None
            else:
                self.logger.info("快慢时间处理已禁用")
                self.chirp_matrix = None
                self.chirp_processing_info = None
            
            if saved_files:
                self.logger.info("✓ 数据保存完成（包含快慢时间矩阵处理）")
                return True
            else:
                self.logger.error("✗ 数据保存失败")
                return False
            
        except Exception as e:
            self.logger.error(f"保存数据失败: {e}")
            return False

    def __del__(self):
        """析构函数"""
        try:
            self.cleanup()
        except Exception:
            # 防止在对象未完全初始化时出错
            pass
